Useful Packages

Math

Geometry

Shader

Pathfinding

Logger

  • By default, there is no logger in the Context.

Using a logger
import "core:log"
Creating a logger
context.logger = log.create_console_logger()
// or
context.logger = log.create_file_logger()
  • .

Options
context.logger = log.create_console_logger(
    opt = log.Options{
        .Level,
        .Terminal_Color,
        // .Short_File_Path,
        .Procedure,
        // .Line,
        // .Thread_Id,
        }
)

Json

Marshal and Unmarshal
  • Struct field tags :

    User :: struct {
        flag: bool, // untagged field
        age:  int    "custom whatever information",
        name: string `json:"username" xml:"user-name" fmt:"q"`, // `core:reflect` layout
    }
    
    • If multiple information is to be passed in the "value" , usually it is specified by separating it with a comma ( , ).

      name: string `json:"username,omitempty",
      
  • About unions :

    • core:encoding/json  is pretty simple when it comes to union s, it just takes the first variant that it can unmarshal without error. For structs it doesn't consider an unknown field to be an error, though, and I don't think there's a way to make it do so

Comparison
  • In Odin :

    • Simple layout :

    for tileset_info in world["defs"].(json.Object)["tilesets"].(json.Array) {
        if tileset_info.(json.Object)["identifier"].(json.String) == "Internal_Icons" {
            continue 
        }
    }
    
    • Practical layout :

    for tileset_info in world["defs"].(json.Object)["tilesets"].(json.Array) {
        tileset_info := item.(json.Object)
        if tileset_info["identifier"].(json.String) == "Internal_Icons" {
            continue
        }
    }
    
  • In Zig :

    • Simple layout :

      for (jsonParsed.value.object.get("defs").?.object.get("tilesets").?.array.items) |item| {
      

            if (std.mem.eql(u8, item.object.get("identifier").?.string, "Internal_Icons")) {
                continue;
            }
        }
    ```

    • Practical layout :

      for (jsonParsed.value.object.get("defs").?.object.get("tilesets").?.array.items) |item| {
      

            const info_tileset = item.object;
            if (std.mem.eql(u8, info_tileset.get("identifier").?.string, "Internal_Icons")) {
                continue;
            }
        }
    ```

  • In Godot :

    • Without reinforcing casting :

      for ts in world.get('defs').get('tilesets'):
          if (ts.get('identifier') == 'Internal_Icons'):
              continue
      
    • Slightly reinforcing casting : (Using like this atm)

      for ts: Dictionary in (world.get('defs') as Dictionary).get('tilesets'):
          if (ts.get('identifier') == 'Internal_Icons'):
              continue
      
    • Reinforcing casting :

      for ts: Dictionary in ((world.get('defs') as Dictionary).get('tilesets') as Array):
          if ((ts.get('identifier') as String) == 'Internal_Icons'):
              continue
      

SQL

Plotting

Audio

Network

  • "0 bytes received means the connection was closed normally/gracefully, and then you have the .Connection_Closed  error for abnormal closes".

  • .Would_Block

    • "it's not an actual error in this case. it just uses the error slot to indicate that you need to wait.

  • Echo server example .

  • Odin-http .

  • odinhttp .

Terminal Utilities

Capturing ctrl + C  in the Terminal

Windows
main :: proc() {
    win_handler_ok := windows.SetConsoleCtrlHandler(win_handler, windows.TRUE)
    if !win_handler_ok {
        log.error("win_handler not ok")
        return
    }

    for !wants_to_exit {
    }
}


wants_to_exit := false


win_handler :: proc "system" (dwCtrlType: windows.DWORD) -> windows.BOOL {
    // fmt.printfln("dwCtrlType: %v", dwCtrlType)
    switch dwCtrlType {
    case windows.CTRL_C_EVENT, windows.CTRL_BREAK_EVENT, windows.CTRL_CLOSE_EVENT:
        wants_to_exit = true
    }
    return windows.TRUE
}
Linux
package shnt

import "core:fmt"
import "core:sys/linux"

_got_int: bool 

_int_handler :: proc "c" (sig: linux.Signal) {
    _got_int = true
}

main :: proc() { 
    sigact: linux.Sig_Action(int) = { 
        handler = _int_handler,
    } 
    old_sigact: ^linux.Sig_Action(int)
    linux.rt_sigaction(.SIGINT, &sigact, old_sigact)
    for !_got_int { } 
    fmt.println("got sigint!")
}

Colors and Strings

Formats

  • odin-mcpx .

    • Using mpc  might be of interest to you if you are...

      • Building a new programming language

      • Building a new data format

      • Parsing an existing programming language

      • Parsing an existing data format

      • Embedding a Domain Specific Language

      • Implementing Greenspun's Tenth Rule

Image Formats
  • odin-assimp .

    • Assimp .

    • List of all file formats supported .

      • Support for BLEND  is deprecated. It is too time-consuming to maintain an undocumented format which contains so much more than we need.

      • No .exr .

    • Can calculate the tangents for each vertex if used a flag during readFile .

  • png :

    • In png, the alpha channel is optional.

    • vendor:stb/image .

      channels, width, height: ^i32
      image.load("file.png", width, height, channels, 4)
      
      • The first 3 are set by the function to read the data, so if you have an RGB image, channels  will be 3  but it'll load 4 because 4  was specified as the desired_channels , so you can do data[:width * height * 4]  to get a []byte .

      • The number of components N is 'desired_channels' if desired_channels is non-zero, or *channels_in_file  otherwise. If desired_channels is non-zero, *channels_in_file  has the number of components that would have been output otherwise. E.g. if you set desired_channels to 4, you will always get RGBA output

    • core:image/png .

    • Performance :

      • Caio:

        • hello, I'm using core:image/png  to read a 4k png image and it seems really  slow, taking 8-10 seconds to complete. This is the code I'm using: png.load_from_file(path, { .alpha_add_if_missing }, context.temp_allocator) . Is there something here I should be aware of? I'm loading the texture to then send it to the GPU with a vulkan host_visible/host_coherent staging buffer, and then to a device_local image. I profiled the whole process and I'm pretty sure this png  is what is slowing things down. Do you have some tips for this? I don't know much about png, so I don't know what to expect, but this seems too much

      • Yawning:

        • if you profile it, my gut feeling is that it is zlib, since we have a naive implementation, but that's just a guess

        • we do try to make core fast, but maintainabily/ease of implementation take priority atm

        • "I think core:image is basically always gonna be slower than stb", I wouldn't say always, this can be made faster, but it's a time/effort/personel thing.

      • Barinzaya:

        • Is that in an optimized build? It's pure Odin code, so optimization settings will  affect it, and they're usually significant.

        • That being said, even in an optimized build, AFAIK stb_image  is typically faster (though it comes with cautions about using it with untrusted images, if that applies to you)

      • Caio:

        • oh yea, with -o:speed  the load time drops to ~1s

        • just out of curiosity: with -o:speed , image/png  takes 344ms to load the 4k image, vs 6ms from stb/image

3D Models
Config Files
General Data Files
  • odin-bml .

    • Binary Markup Language (BML) is an XML scheme for describing structured binary data. The library contains a protocol parser, a binary data parser, as well as a C header emitter.

Markdown
Other Parsers
Debug
  • odin-pdb .

    • Reads Microsoft PDB (Program Database) files. Enables stacktracing on Windows for The Odin Programming Language.

Media

Hot-Reload

Etc

  • https://github.com/anguelesperanza/controller-to-kbm